package com.wans.ssq.service.Impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wans.common.constans.CustomExceptionEnum;
import com.wans.common.exception.CustomRunningException;
import com.wans.common.redis.RedisPrefix;
import com.wans.common.redis.RedisUtils;
import com.wans.common.result.ResponseResult;
import com.wans.model.common.PaginationParam;
import com.wans.model.lottery.ssq.dos.SSQ;
import com.wans.model.lottery.ssq.dtos.SSQHistoryDTO;
import com.wans.ssq.mapper.SSQMapper;
import com.wans.ssq.service.SSQService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;

@Service
@Slf4j
public class SSQHistoryServiceImpl implements SSQService {

    // 查询 ssq 数据库
    @Autowired
    private SSQMapper ssqMapper;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private ObjectMapper objectMapper;

    /**
     * 获取数据库中最新的期次
     *
     * @return 最新的期次
     */
    @Override
    public ResponseResult<SSQ> getNewHistoryCode() {
        return ResponseResult.success(ssqMapper.getNewHistoryCode());
    }

    /**
     * 插入一条数据
     *
     * @param ssq 一条数据
     * @return 响应体
     */
    @Override
    @Transactional
    public ResponseResult<Integer> saveNewHistoryCode(SSQ ssq) {

        Integer inserted = ssqMapper.saveHistoryCode(ssq);

        if (inserted == null || inserted == 0)
            return ResponseResult.fail(CustomExceptionEnum.USER_SSQ_INSERT_ERROR.getErrorMessage(), 0);

        // 清除所有相关的历史记录缓存
        clearCache();

        return ResponseResult.success(inserted);
    }

    /**
     * 获取历史记录列表
     *
     * @param ssqHistoryDTO 分页参数等
     * @return 分页后的数据
     */
    @Override
    public ResponseResult<List<SSQ>> listHistory(SSQHistoryDTO ssqHistoryDTO) {

        // 计算 limit 参数
        ssqHistoryDTO.calculatePagination();

        // 生成唯一缓存键（包含分页参数）
        String cacheKey = generateCacheKey(ssqHistoryDTO);

        try {
            // 尝试从缓存读取
            String cacheValue = redisUtils.get(cacheKey);
            if (cacheValue != null && !cacheValue.isEmpty()) {
                // 此时缓存数据不为 null 也不是空字符串
                // 使用 TypeReference 指定确切的泛型类型
                TypeReference<List<SSQ>> typeRef = new TypeReference<>() {
                };
                List<SSQ> cachedData = objectMapper.readValue(cacheValue, typeRef);
                if (cachedData != null) {
                    return ResponseResult.success(cachedData);
                }
            }
        } catch (JsonProcessingException e) {
            throw new CustomRunningException(CustomExceptionEnum.JSON_PROCESS_EX);
        }

        // 缓存未命中则查询数据库
        List<SSQ> result = ssqMapper.listHistory(ssqHistoryDTO);

        try {
            // 将结果写入缓存
            if (!result.isEmpty()) {
                redisUtils.set(cacheKey, objectMapper.writeValueAsString(result));
            }
        } catch (JsonProcessingException e) {
            throw new CustomRunningException(CustomExceptionEnum.JSON_PROCESS_EX);
        }

        return ResponseResult.success(result);
    }


    /**
     * 缓存数据使用逻辑 - 初始化缓存
     * @param paginationCache 分页缓存
     */
    @Override
    public void cacheHistory(PaginationParam paginationCache) {
        SSQHistoryDTO cacheParam = new SSQHistoryDTO();
        cacheParam.setCurrentPage(paginationCache.getCurrentPage());
        cacheParam.setPageSize(paginationCache.getPageSize());
        cacheParam.calculatePagination();
        // 查询数据库
        List<SSQ> result = ssqMapper.listHistory(cacheParam);

        // 生成唯一缓存键（包含分页参数）
        String cacheKey = generateCacheKey(cacheParam);

        try {
            // 将结果写入缓存
            if (!result.isEmpty()) {
                redisUtils.set(cacheKey, objectMapper.writeValueAsString(result));
            }
        } catch (JsonProcessingException e) {
            throw new CustomRunningException(CustomExceptionEnum.JSON_PROCESS_EX);
        }
    }

    /**
     * 初始化前的清除缓存 - 亦可直接清除双色球历史记录缓存
     */
    public void clearCache(){
        // 清除所有相关的历史记录缓存
        Set<String> keys = redisUtils.keys(RedisPrefix.LOTTERY_SSQ_HISTORY_PREFIX.getPrefix() + "*");
        if (keys != null && !keys.isEmpty()) {
//            redisUtils.delete(keys);
            // 如果数据量大可使用异步清除
            CompletableFuture.runAsync(() -> redisUtils.delete(keys));
        }
    }

    // 生成带参数的缓存键
    private String generateCacheKey(SSQHistoryDTO dto) {
        return RedisPrefix.LOTTERY_SSQ_HISTORY_PREFIX.getPrefix() +
                "page:" + dto.getCurrentPage() +
                ":size:" + dto.getPageSize();
    }
}
